---
import '../../global.css'
import { firestore, Game, getGame, getSession, moveGameToBackendSaving } from '../../lib/game-saving/account'
import Editor from '../../components/big-interactive-pages/editor'
import StandardHead from '../../components/standard-head.astro'
import { signal } from '@preact/signals'
import { ConnectionStatus, PersistenceStateKind, RoomState, type PersistenceState } from '../../lib/state'
import MobileUnsupported from '../../components/popups-etc/mobile-unsupported'
import { mobileUserAgent } from '../../lib/utils/mobile'
import { isAccountWhitelistedToUseCollabAndSavingBetaFeatures } from '../../lib/game-saving/account'

const session = await getSession(Astro.cookies)
if (!session) {
	console.log("No session found, redirecting to login");
	return Astro.redirect(`/login?to=${Astro.request.url}`, 302)
}

let persistenceState;
let isMobile;
let roomState;
let _persistenceState: PersistenceState | undefined

async function handleTutorial(game: Game) : Promise<[string[] | undefined, number | undefined]>{
	const fileRegexp = /^.*\/(.+)-(\d+)\.md$/

	if (game.tutorialName) {
		const files = await Astro.glob('/games/*.md')
			
		return [files.filter(file => {
			const regexedFile = file.file.match(fileRegexp)
			return regexedFile && regexedFile[1] === game.tutorialName
		})
		?.map(md => md.compiledContent()), game.tutorialIndex]
	}

	return [undefined, undefined]
}

async function handlePersistenceState(isSessionFull : boolean, game : Game, tutorial : string[] | undefined, tutorialIndex : number | undefined) : Promise<PersistenceState | undefined>{
	if (isSessionFull) {
		if (game.unprotected) {
			await firestore.collection('games').doc(game.id).update({ unprotected: false })
			game.unprotected = false
		}
		if (Astro.cookies.get('sprigTempGame').value === game.id)
			Astro.cookies.delete('sprigTempGame', { path: '/' })
	} else {
		if (!game.unprotected) return undefined;
	}

	return {
		kind: PersistenceStateKind.PERSISTED,
		session,
		cloudSaveState: 'SAVED',
		game,
		tutorial,
		tutorialIndex,
		stale: false
	} as PersistenceState
}

function checkRoomAccess(game : Game, userEmail : string){
	if(game.roomParticipants?.filter(participant => participant.userEmail === userEmail)[0]?.isBanned) {
		console.log("User is banned from this room");
		return Astro.redirect('/404', 302)
	}
	if(!game.unprotected && game.password == undefined) {
		console.log("Protected game has no password set");
		return Astro.redirect('/404', 302)
	}
	return undefined;
}

console.log(`Attempting to load game with ID: ${Astro.params.id}`);
const game = await getGame(Astro.params.id!)

if (!game) {
	console.log(`Game not found in database for ID: ${Astro.params.id}`);
	return Astro.redirect('/404', 302)
}

console.log(`Found game: ${game.id}, name: ${game.name}, unprotected: ${game.unprotected}`);

// Disable beta features for review games (unprotected games)
let shouldGameUseBetaCollabAndSavingFeatures = false;
// if (!game.unprotected) {
// 	const isWhitelisted = await isAccountWhitelistedToUseCollabAndSavingBetaFeatures(session.user.id, session.user.email);
// 	shouldGameUseBetaCollabAndSavingFeatures = false;//Boolean(isWhitelisted) || Boolean(game.isSavedOnBackend);
// }

if(shouldGameUseBetaCollabAndSavingFeatures){
	console.log("Game is using beta collab and saving features");
	if(!game.isSavedOnBackend){
		console.log("Game is not saved on backend, moving it...");
		return Astro.redirect('/404', 302)
	}
	let checkRoom = false; // Whether or not to check whether the user has access to the room he's trying to enter
	if(game.ownerId !== session.user.id) {
		console.log("User is not the owner, checking room access");
		checkRoom = true;
	}

	let [tutorial, tutorialIndex] = await handleTutorial(game);
	if(checkRoom){
		console.log("Setting up persistence state for collab mode");
		_persistenceState = {
			kind: PersistenceStateKind.COLLAB,
			game: game.id,
			password: undefined,
			cloudSaveState: "SAVED",
			session: session,
			stale: false
		} as PersistenceState
		let roomAccess = checkRoomAccess(game, session.user.email)
		if(roomAccess != undefined) return roomAccess
	} else {
		console.log("Setting up persistence state for single user mode");
		_persistenceState = await handlePersistenceState(session.session.full, game, tutorial, tutorialIndex)
		if(!_persistenceState) {
			console.log("Failed to set up persistence state, redirecting to login");
			return Astro.redirect(`/login?to=${Astro.request.url}`, 302)
		}
	}

	roomState = signal<RoomState>({
		connectionStatus: ConnectionStatus.DISCONNECTED,
		roomId: game.id,
		participants: [],
	})
} else {
	console.log("Using standard game mode");
	// Allow access to unprotected games regardless of owner
	if (!game.unprotected && game.ownerId !== session.user.id) {
		console.log("Protected game access denied - user is not owner");
		return Astro.redirect('/404', 302)
	}

	let [tutorial, tutorialIndex] = await handleTutorial(game)
	
	_persistenceState = await handlePersistenceState(session.session.full, game, tutorial, tutorialIndex)
	if(!_persistenceState) {
		console.log("Failed to set up persistence state");
		return Astro.redirect(`/login?to=${Astro.request.url}`, 302)
	}
}

persistenceState = signal<PersistenceState>(_persistenceState)
isMobile = mobileUserAgent(Astro.request.headers.get('user-agent') ?? '')
---
<html lang='en'>
	<head>
		<StandardHead title='Editor' />
	</head>
	<body>
		<Editor
			client:load
			persistenceState={persistenceState}
			roomState={roomState}
			cookies={{
				outputAreaSize: Astro.cookies.get('outputAreaSize').number(),
				helpAreaSize: Astro.cookies.get('helpAreaSize').number(),
				hideHelp: Astro.cookies.get('hideHelp').boolean()
			}}
		/>
		{isMobile ? <MobileUnsupported /> : null}
	</body>
</html>